﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.Display;
using System.Collections;
using ESRI.ArcGIS.DataSourcesRaster;
using PlanningGIS.Win.Controls;
using PlanningGIS.Util.Management;
using PlanningGIS.Engine.Controls;

namespace PlanningGIS.Symbol
{
    /// <summary>
    /// 作用：栅格分级渲染
    /// </summary>
    public partial class RasterClassify : UserControl
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public RasterClassify()
        {
            InitializeComponent();

            for (int i = 1; i <= 32; i++)
            {
                cbxClassesNum.Items.Add(i);
            }
            cbxClassesNum.SelectedIndex = 0;
            cmbColorRamp.Init();
            colorNoData.InitStyle();
            colorNoData.ImageVisiable = false;
        }
        
        /// <summary>
        /// 色带
        /// </summary>
        IColorRamp myColorRamp;

        /// <summary>
        /// 分类渲染
        /// </summary>
        IRasterClassifyColorRampRenderer classifyColorRampRenderer;

        /// <summary>
        /// 当前作用的栅格图层
        /// </summary>
        private IRasterLayer m_pRasterLayer;
        /// <summary>
        /// 当前作用的栅格图层
        /// </summary>
        public IRasterLayer RasterLayer
        {
            get { return m_pRasterLayer; }
            set
            {
                m_pRasterLayer = value;
                InitialClassifyFrame();
            }
        }

        /// <summary>
        /// 设置栅格分组渲染
        /// </summary>
        public void SetRenderer()
        {
            if (dgrdvwClassifiy.Rows.Count == 0)
            {
                MsgHelper.ShowInfomationMsgbox("栅格分级数或分组颜色未设置正确！\n请正确设置栅格分级数和分组颜色！");
                return;
            }
            IRasterClassifyColorRampRenderer pRasterClassifyColorRampRenderer = new RasterClassifyColorRampRendererClass();
            IRasterRenderer pRasterRender = pRasterClassifyColorRampRenderer as IRasterRenderer;
            pRasterRender.Raster = this.m_pRasterLayer.Raster;
            IRasterRendererColorRamp pRasterRendererColorRamp = pRasterClassifyColorRampRenderer as IRasterRendererColorRamp;
            pRasterRendererColorRamp.ColorRamp = cmbColorRamp.SelectedColorRamp;
            pRasterRendererColorRamp.ColorScheme = cmbColorRamp.ColorScheme;
            pRasterClassifyColorRampRenderer.ClassCount = int.Parse(cbxClassesNum.Text);
            //级色
            for (int i = 0; i < pRasterClassifyColorRampRenderer.ClassCount; i++)
            {
                StyleItem itm = dgrdvwClassifiy.Rows[i].Tag as StyleItem;
                pRasterClassifyColorRampRenderer.set_Break(i, itm.BreakValue);
                pRasterClassifyColorRampRenderer.set_Symbol(i, itm.Symbol);
                if (dgrdvwClassifiy.Rows[i].Cells[2].Value.ToString().Trim().Length == 0)
                {
                    dgrdvwClassifiy.Rows[i].Cells[2].Value = dgrdvwClassifiy.Rows[i].Cells[1].Value;
                }
                pRasterClassifyColorRampRenderer.set_Label(i, dgrdvwClassifiy.Rows[i].Cells[2].Value.ToString());
            }
            pRasterClassifyColorRampRenderer.set_Break(pRasterClassifyColorRampRenderer.ClassCount, double.Parse(dgrdvwClassifiy.Tag as string));
            //无值象素显示颜色
            IRasterDisplayProps pRasterDisplayProps = pRasterClassifyColorRampRenderer as IRasterDisplayProps;
            pRasterDisplayProps.NoDataColor = ESRI.ArcGIS.ADF.Connection.Local.Converter.ToRGBColor(this.colorNoData.SelectedColor);
            if (colorNoData.SelectedColor.Name == "ffedeada" || colorNoData.SelectedColor.Name == "Control")
            {
                pRasterDisplayProps.NoDataColor.NullColor = true;
                pRasterDisplayProps.TransparencyValue = 100;
            }
            //山影
            IHillShadeInfo pHillShadeInfo = pRasterClassifyColorRampRenderer as IHillShadeInfo;
            pHillShadeInfo.UseHillShade = chkClassifyShowHillShadow.Checked;
            if (chkClassifyShowHillShadow.Checked)
            {
                if (txtZValueClaasify.Text.Length == 0)
                {
                    txtZValueClaasify.Text = "0.0001";
                }
                pHillShadeInfo.ZScale = Convert.ToDouble(txtZValueClaasify.Text);
            }
            pRasterRender.Update();
            this.m_pRasterLayer.Renderer = pRasterClassifyColorRampRenderer as IRasterRenderer;
        }

        /// <summary>
        /// 初始化分级符号化页面
        /// </summary>
        private void InitialClassifyFrame()
        {
            if (m_pRasterLayer == null) return;

            IRasterRenderer render = m_pRasterLayer.Renderer;
            if (!(render is IRasterClassifyColorRampRenderer))
            {
                RefreshData();
                return;
            } 
            classifyColorRampRenderer = render as IRasterClassifyColorRampRenderer;
            IRasterRendererColorRamp rendererColorRamp = classifyColorRampRenderer as IRasterRendererColorRamp;
            cmbColorRamp.ColorScheme = rendererColorRamp.ColorScheme;
            myColorRamp = rendererColorRamp.ColorRamp;
            if (classifyColorRampRenderer.ClassCount < 14)
            {
                cbxClassesNum.Text = classifyColorRampRenderer.ClassCount.ToString();
                //无值象素显示颜色
                IRasterDisplayProps pRasterDisplayProps = classifyColorRampRenderer as IRasterDisplayProps;
                if (pRasterDisplayProps != null)
                {
                    if (!pRasterDisplayProps.NoDataColor.NullColor)
                    {
                        IRgbColor pRGBNocolor = pRasterDisplayProps.NoDataColor as ESRI.ArcGIS.Display.IRgbColor;
                        this.colorNoData.SelectedColor = ESRI.ArcGIS.ADF.Connection.Local.Converter.FromRGBColor(pRGBNocolor);
                    }
                }
                //山影
                IHillShadeInfo pHillShadeInfo = classifyColorRampRenderer as IHillShadeInfo;
                if (pHillShadeInfo != null)
                {
                    chkClassifyShowHillShadow.Checked = pHillShadeInfo.UseHillShade;
                    txtZValueClaasify.Text = pHillShadeInfo.ZScale.ToString();
                }
            }
            //如果该栅格图层的分级数大于颜色板的分级数，或者该栅格数据的各颜色在任何一个颜色板中都找不全，则根据它自身的颜色
            //来填充iGrid中的颜色(就算找到了，也得重新填充，具体原因见上面的解释)
            dgrdvwClassifiy.Rows.Clear();            
            for (int i = 0; i < classifyColorRampRenderer.ClassCount; i++)
            {
                int rowIndex = dgrdvwClassifiy.Rows.Add();
                StyleItem itm = new StyleItem();
                itm.BreakValue = classifyColorRampRenderer.get_Break(i);
                itm.BreakNextValue = classifyColorRampRenderer.get_Break(i + 1);
                itm.Symbol = classifyColorRampRenderer.get_Symbol(i);
                dgrdvwClassifiy.Rows[rowIndex].Cells[0].Style.BackColor = PlanningGIS.ArcGIS.Convertor.IColor2Color(((IFillSymbol)itm.Symbol).Color);
                dgrdvwClassifiy.Rows[rowIndex].Cells[1].Value = itm.BreakValue.ToString("F") + "-" + itm.BreakNextValue.ToString("F");
                dgrdvwClassifiy.Rows[rowIndex].Cells[2].Value = classifyColorRampRenderer.get_Label(i);
                dgrdvwClassifiy.Rows[rowIndex].Tag = itm;
            }
            dgrdvwClassifiy.Tag = classifyColorRampRenderer.get_Break(classifyColorRampRenderer.ClassCount).ToString("F");
            cmbColorRamp.SelectedIndexChanged += new EventHandler(cmbColorRamp_SelectedIndexChanged);
        }

        /// <summary>
        /// 色带选择改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cmbColorRamp_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                myColorRamp = cmbColorRamp.SelectedColorRamp;
                if (String.IsNullOrWhiteSpace(this.cbxClassesNum.Text)) return;
                int classCount = int.Parse(this.cbxClassesNum.Text);
                if (dgrdvwClassifiy.Rows.Count == classCount)
                {
                    for (int i = 0; i < classCount; i++)
                    {
                        ISimpleFillSymbol fillSymbol = new SimpleFillSymbol();
                        fillSymbol.Color = myColorRamp.get_Color((i * myColorRamp.Size) / (classCount + 1));
                        fillSymbol.Style = esriSimpleFillStyle.esriSFSSolid;
                        fillSymbol.Outline.Width = 0.4;
                        dgrdvwClassifiy.Rows[i].Cells[0].Style.BackColor = PlanningGIS.ArcGIS.Convertor.IColor2Color(fillSymbol.Color); 
                        (dgrdvwClassifiy.Rows[i].Tag as StyleItem).Symbol = (ISymbol)fillSymbol;
                    }
                }
                else
                {
                    RefreshData();
                }
            }
            catch
            {
            }
        }
  
        /// <summary>
        /// 是否显示阴影效果
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chkClassifyShowHillShadow_CheckedChanged(object sender, EventArgs e)
        {
            txtZValueClaasify.Enabled = chkClassifyShowHillShadow.Checked;
        }

        /// <summary>
        /// 分类数选择改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbClassesNum_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (myColorRamp != null)
            {
                RefreshData();
            }
        }

        /// <summary>
        /// 刷新数据
        /// </summary>
        private void RefreshData()
        {
            int classCount = int.Parse(this.cbxClassesNum.Text);
            dgrdvwClassifiy.Rows.Clear();
            IRasterClassifyColorRampRenderer pRClassRend = new RasterClassifyColorRampRenderer() as IRasterClassifyColorRampRenderer;
            if (m_pRasterLayer != null)
            {
                IRasterRenderer pRRend = pRClassRend as IRasterRenderer;

                IRaster pRaster = m_pRasterLayer.Raster;
                IRasterBandCollection pRBandCol = pRaster as IRasterBandCollection;
                IRasterBand pRBand = pRBandCol.Item(0);
                if (pRBand.Histogram == null)
                {
                    pRBand.ComputeStatsAndHist();
                }
                pRRend.Raster = pRaster;
                pRClassRend.ClassCount = classCount;
                pRRend.Update(); for (int i = 0; i < classCount; i++)
                {
                    StyleItem itm = new StyleItem();
                    ISimpleFillSymbol fillSymbol = new SimpleFillSymbolClass();
                    fillSymbol.Color = myColorRamp.get_Color((i * myColorRamp.Size) / (classCount + 1));
                    fillSymbol.Style = esriSimpleFillStyle.esriSFSSolid;
                    fillSymbol.Outline.Width = 0.4;
                    itm.Symbol = (ISymbol)fillSymbol;
                    itm.BreakValue = pRClassRend.get_Break(i);
                    itm.BreakNextValue = pRClassRend.get_Break(i + 1);

                    string strLabel;
                    if (i == 0)
                    {
                        strLabel = itm.BreakValue.ToString() + "-" + itm.BreakNextValue.ToString();
                    }
                    else
                    {
                        strLabel = (itm.BreakValue + 0.00001).ToString() + "-" + itm.BreakNextValue.ToString();
                    }
                    int rIndex = dgrdvwClassifiy.Rows.Add();
                    dgrdvwClassifiy.Rows[rIndex].Cells[0].Style.BackColor = PlanningGIS.ArcGIS.Convertor.IColor2Color(fillSymbol.Color);
                    dgrdvwClassifiy.Rows[rIndex].Cells[1].Value = itm.BreakValue.ToString() + "-" + itm.BreakNextValue.ToString();
                    dgrdvwClassifiy.Rows[rIndex].Cells[2].Value = strLabel;
                    dgrdvwClassifiy.Rows[rIndex].Tag = itm;
                }
                dgrdvwClassifiy.Tag = pRClassRend.get_Break(classCount - 1).ToString();
            }
            


            //int classCount = int.Parse(this.cbxClassesNum.Text);            
            //dgrdvwClassifiy.Rows.Clear();
            //double maxBreak = 254;
            //double minBreak = 0;
            //if (m_pRasterLayer != null)
            //{
            //    IRasterRenderer pRasterRender = m_pRasterLayer.Renderer;
            //    IRasterStretchMinMax pRasterStretchMinMax = pRasterRender as IRasterStretchMinMax;
            //    maxBreak = pRasterStretchMinMax.StretchMax;
            //    minBreak = pRasterStretchMinMax.StretchMin;
            //}

            //double rate = Math.Round((maxBreak - minBreak) / classCount, 4);
            //for (int i = 0; i < classCount; i++)
            //{
            //    StyleItem itm = new StyleItem();
            //    ISimpleFillSymbol fillSymbol = new SimpleFillSymbolClass();
            //    fillSymbol.Color = myColorRamp.get_Color((i * myColorRamp.Size) / (classCount + 1));
            //    fillSymbol.Style = esriSimpleFillStyle.esriSFSSolid;
            //    fillSymbol.Outline.Width = 0.4;
            //    itm.Symbol = (ISymbol)fillSymbol;
            //    itm.BreakValue = minBreak + rate * i;
            //    itm.BreakNextValue = minBreak + (rate * (i + 1));

            //    string strLabel;
            //    if (i == 0)
            //    {
            //        strLabel = minBreak.ToString() + "-" + itm.BreakNextValue.ToString();
            //    }
            //    else
            //    {
            //        strLabel = (minBreak + 0.00001).ToString() + "-" + itm.BreakNextValue.ToString();
            //    }                
            //    int rIndex = dgrdvwClassifiy.Rows.Add();
            //    dgrdvwClassifiy.Rows[rIndex].Cells[0].Style.BackColor = PlanningGIS.ArcGIS.Convertor.IColor2Color(fillSymbol.Color); 
            //    dgrdvwClassifiy.Rows[rIndex].Cells[1].Value = itm.BreakValue.ToString() + "-" + itm.BreakNextValue.ToString();
            //    dgrdvwClassifiy.Rows[rIndex].Cells[2].Value = strLabel;
            //    dgrdvwClassifiy.Rows[rIndex].Tag = itm;
            //}
            //dgrdvwClassifiy.Tag = maxBreak.ToString();
        }

        /// <summary>
        /// 
        /// </summary>
        protected class StyleItem
        {
            /// <summary>
            /// 
            /// </summary>
            public double BreakValue { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public double BreakNextValue { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public ISymbol Symbol { get; set; }
        }
    }
}
